package menuedit;

import guis.AbstractTableGUI;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import datacontainers.Category;
import datacontainers.Dish;
import datacontainers.Menu;

public class MenuEditGUI extends AbstractTableGUI {

	// TODO will be variable loads from settings
	final int editKey = SWT.CR;
	final int delKey = SWT.DEL;

	private MenuEditInterface controller;
	private DateTime menuToDate;

	private Text edit;
	private Combo selector;

	MenuEditGUI(MenuEditInterface controller, Composite tshell) {
		this.controller = controller;

		this.tshell = tshell;
		this.tshell.setLayout(new FormLayout());

		initLeftPanel();
		initTable();
	}

	public void showMenu(Menu menu) {
		table.removeAll();
		for (Category cat : Category.values()) {
			addCategoryItem(cat);
			for (Dish item : menu.getCategory(cat)) {
				addTableItem(item);
			}
			addFreeDishItem(cat);
		}
	}

	void initLeftPanel() {
		createLeftPanel();

		Label dateLabel = new Label(leftPanel, 0);
		dateLabel.setText("New menu end date:");
		dateLabel.setBounds(0, 0, 120, 30);

		menuToDate = new DateTime(leftPanel, SWT.BORDER);
		menuToDate.setBounds(0, 30, 120, 30);
		menuToDate.setDay(menuToDate.getDay() + 1); // menu actual to tomorrow

		Button saveButton = new Button(leftPanel, SWT.NONE);
		saveButton.setBounds(0, 60, 120, 30);
		saveButton.setText("Save menu");

		saveButton.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				controller.saveMenu();
			}

		});
	}

	void initTable() {
		createMainPanel();
		createTable((new String[] { "id", "Name", "Description", "Cost" }));
		table.setEnabled(true);

		table.getColumn(0).setWidth(0);
		table.getColumn(0).setResizable(false);

		table.addKeyListener(new KeyListener() {

			@Override
			public void keyPressed(KeyEvent arg0) {
				tableKeyPressed(arg0.keyCode);
			}

			@Override
			public void keyReleased(KeyEvent arg0) {
			}

		});

		table.addMouseListener(new MouseListener() {

			@Override
			public void mouseDoubleClick(MouseEvent arg0) {
				if (arg0.button == java.awt.event.MouseEvent.BUTTON1)
					tableKeyPressed(java.awt.event.KeyEvent.VK_ENTER);

				if (arg0.button == java.awt.event.MouseEvent.BUTTON3)
					tableKeyPressed(java.awt.event.KeyEvent.VK_DELETE);
			}

			@Override
			public void mouseDown(MouseEvent arg0) {
				//

			}

			@Override
			public void mouseUp(MouseEvent arg0) {
				//
			}
		});

	}

	private void tableKeyPressed(int key) {
		if (key == SWT.CR) {

			if (table.getItem(table.getSelectionIndex()).getData("dish") != null) {
				if (!table.getItem(table.getSelectionIndex()).getText(1)
				        .equalsIgnoreCase("add dish")) {
					table.getItem(table.getSelectionIndex()).setData(
					        "editIndex", new Integer(-1));
					editItemMode(table.getSelectionIndex());
				} else {
					addItemMode(table.getSelectionIndex());
				}

			}
		}

		if (key == SWT.DEL) {
			// TODO add delete-request
			deleteItem(table.getSelectionIndex());
		}
	}

	private void deleteItem(int selectionIndex) {
		TableItem item = table.getItem(selectionIndex);

		if ((item.getData("dish") != null)
		        & (!item.getText(0).equalsIgnoreCase(""))) {
			// delete as dish
			item.dispose();
		} else {

			if ((item.getData("category") != null)
			        & (!item.getText(1).equalsIgnoreCase("add category"))) {
				while (item.getData("category") != null) {
					item.dispose();
					item = table.getItem(selectionIndex);
				}
			}
		}
	}

	private void addItemMode(int index) {

		// add new item
		TableItem newDishItem = new TableItem(table, SWT.NONE, index);

		newDishItem.setText(0, "0");
		newDishItem.setData("dish",
		        ((Dish) table.getItem(index + 1).getData("dish")));

		// create and set editor
		selector = new Combo(table, SWT.DROP_DOWN);
		selector.setBounds(newDishItem.getBounds(1));
		selector.setFocus();
		selector.setListVisible(true);

		selector.setData("item", newDishItem);

		selector.addKeyListener(new KeyListener() {

			TableItem item = table.getItem(table.indexOf((TableItem) selector
			        .getData("item")));
			Dish dish;

			@Override
			public void keyPressed(KeyEvent arg0) {
				if (arg0.keyCode == SWT.CR) {
					if (selector.getSelectionIndex() >= 0) {
						// add dish from list
						dish = (Dish) selector.getData(selector
						        .getItem(selector.getSelectionIndex()));
						item.setData("dish", dish);
						dishToTableItem(dish, item);
					} else {
						// adding new dish
						dish = ((Dish) item.getData("dish"));
						dish.setName(selector.getText());
						item.setText(1, selector.getText());
						controller.addDish(dish);
					}
					// TODO add checking for table not have this dish

					item.setData("editIndex", 2);
					editItemMode(table.indexOf(item));
					controller.addDish(dish);
					selector.dispose();
				}

				if (arg0.keyCode == SWT.ESC) {
					int selected = table.getSelectionIndex(); // to get from
					// selector

					item.dispose();
					table.setSelection(selected);
					table.setCapture(true);
					selector.dispose();
				}
			}

			@Override
			public void keyReleased(KeyEvent arg0) {
				if (String.valueOf(arg0.character).matches("\\w")) {

					selector.remove(0, selector.getItemCount() - 1);

					for (Dish t : controller.getDishVariants(
					        ((Dish) item.getData("dish")).getCategory(),
					        selector.getText())) {
						selector.add(t.getName() + "(" + t.getDescription()
						        + ")");
						selector.setData(t.getName() + "(" + t.getDescription()
						        + ")", t);

					}
				}
			}

		});
		// editMode();
	}

	private void editItemMode(int itemIndex) {
		edit = new Text(table, 0);
		int editInColumn = (Integer) table.getItem(itemIndex).getData(
		        "editIndex");

		edit.setData("item", table.getItem(itemIndex)); // save item to editor

		if (editInColumn == -1) {
			editInColumn = 1;
			table.getItem(itemIndex).setData("editIndex", editInColumn);
		}

		// set Edit into line
		edit.setBounds(table.getItem(itemIndex).getBounds(editInColumn));
		// load text
		edit.setText(table.getItem(itemIndex).getText(editInColumn));
		// save edit widget to item

		// set focus to edit
		edit.setFocus();
		edit.setSelection(0, edit.getText().length());

		edit.addKeyListener(new KeyListener() {
			@Override
			public void keyPressed(KeyEvent arg0) {
				if (arg0.keyCode == SWT.CR) {

					// load edit from item
					// Text

					TableItem item = table.getItem(table
					        .indexOf((TableItem) edit.getData("item")));

					int editInColumn = (Integer) (item.getData("editIndex"));
					// save new data
					// item.setText(editInColumn, t.getText()); //to table
					item.setText(editInColumn, edit.getText()); // to table

					if (editInColumn < 3) {
						// next column load
						editInColumn++;
						edit.setBounds(item.getBounds(editInColumn));
						edit.setText(item.getText(editInColumn));
						edit.setFocus();
						edit.setSelection(0, edit.getText().length());

						item.setData("editIndex", editInColumn); // save
					} else {
						// save data and end editing

						if ((item.getText(1) != "") & (item.getText(3) != "")) {
							Dish dish = (Dish) item.getData("dish");
							dish.setName(item.getText(1));
							dish.setDescription(item.getText(2));
							dish.setCost(Double.parseDouble(item.getText(3)));
							table.setSelection(table.getSelectionIndex() + 1);
							controller.updateDish(dish);
						}
						// else {editItemMode();}
						edit.dispose();
					}

				}
			}

			@Override
			public void keyReleased(KeyEvent arg0) {
			}
		});
	}

	void addFreeDishItem(Category cat) {
		TableItem i = new TableItem(table, SWT.BOLD);
		i.setText(1, "add dish");
		i.setData("dish", new Dish(0, cat, "", "", 0.0));
		i.setForeground(centerShell.getDisplay().getSystemColor(SWT.COLOR_GRAY));
	}

	public void disposeControls() {
		//

	}

}
